use std::cell::RefCell;
/**
    闭包
        可以存储在变量中或着作为参数传递给其他函数的匿名函数
        通常不需要像函数那样标注参数或返回值类型
        一般不会暴露给用的接口中使用 通常很短，只限在上下文中使用，以便于编译器推断其参数和返回值
        闭包只会存在一个类型 并返回一个类型
       用途：
            弱指针

 */
#[derive(Debug)]
enum Color {
    RED,
    BLUE,
    GREEN
}
struct User {
    name: String,
    like_color: Color
}
struct Shift {
    shifes: Vec<Color>
}
impl Shift {
    fn give_shift(&self, color: Option<Color>) -> Color {
        //闭包 unwrap_or_else 捕获解开后为none的情况，然后执行其中的匿名函数
        color.unwrap_or_else(|| {
            println!("color");
            Color::GREEN
        })
    }
}
fn main() {
    let mut my_shifts = Shift {
        shifes: vec![Color::RED, Color::BLUE, Color::GREEN]
    };
    let color = my_shifts.give_shift(None);
    println!("{:?}", color);

    //闭包的不可变引用获取值
    // println!("color: {:?}", my_shifts.shifes);
    // let only_borrows = || println!("only_borrows_color: {:?}", my_shifts.shifes);
    // only_borrows();
    // println!("color: {:?}", my_shifts.shifes);

    //闭包的可变引用获得值
    println!("color: {:?}", my_shifts.shifes);
    let mut only_borrows = ||  my_shifts.shifes.push(Color::RED);
    //无法在其中间进行引用，因为此时引用已经赋值给了闭包
    // println!("color: {:?}", my_shifts.shifes);
    only_borrows();
    //闭包结束 引用结束 后续可以继续获取
    println!("color: {:?}", my_shifts.shifes);

    //闭包获得数据的所有权
    println!("color: {:?}", my_shifts.shifes);
    let mut move_only_borrows = move ||  println!("move_only_borrows: {:?}", my_shifts.shifes);
    //所有权已经转移  无法再进行引用
    //println!("color: {:?}", my_shifts.shifes);
}
